(function($) {
    $.fn.uiTable = function(method) {
        switch(method) {
            case 'selected':
                var selected = [], tbody = $(this).find('tbody td.col_chk input:checked');
                tbody.each(function(i, n) {
                    selected[i] = $(n).val();
                });
                return selected;
            case 'selectAll':
                if ($(this).find('th.col_chk input:checkbox').attr('checked')) {
                    $(this).find('th.col_chk input:checkbox').removeAttr('checked').trigger('change');
                } else {
                    return $(this).find('th.col_chk input:checkbox').attr('checked', true).trigger('change');
                }
            default:
                $(this).each(function(i, tb) {
                    var $tb = $(tb), tbody = $tb.find('tbody');
                    $tb.find('th.col_chk').delegate('input:checkbox', 'change', function() {
                        if ($(this).attr('checked')) {
                            tbody.find('td.col_chk input:checkbox').attr('checked', true).trigger('change');
                        } else {
                            tbody.find('td.col_chk input:checkbox').removeAttr('checked').trigger('change');
                        }
                    });
                    $tb.find('td.has-row-actions').live('mouseover mouseout', function(e) {
                        if (e.type == 'mouseout') {
                            $(this).find('div.row-actions').css('visibility', 'hidden');
                        } else {
                            $(this).find('div.row-actions').css('visibility', 'visible');
                        }
                    });
                });
        }
        return $(this);
    };
    $.fn.uiTreeTable = function() {
        $(this).each(function() {
            var $this = $(this);
            $('tbody tr', $this).each(function(i, tr) {
                var row = $(tr), nodeId = row.attr('id');
                addHandl(nodeId, row, $this);
                if (row.hasClass('expanded')) {
                    expandNode(nodeId, row, $this);
                }
            });

            $('tbody td i.handl', $this).live('click', function() {
                var hd = $(this), row = hd.parent().parent();
                var nodeId = row.attr('id');

                if (row.hasClass('expanded')) {
                    row.addClass('collapsed').removeClass('expanded');
                    collapseNode(nodeId, row, $this);
                } else {
                    row.addClass('expanded').removeClass('collapsed');
                    expandNode(nodeId, row, $this);
                }
            });
        });

        function addHandl(id, row, table) {
            if (row.find('i.shim').length > 0) {
                return;
            }
            if (table.find('.item-of-' + id).length) {
                row.find('.tree-handl').prepend($('<i class="handl shim icon-folder-close"></i>'));
                row.data('moved', moveRows(id, row));
                row.data('left', 0);
            } else {
                row.find('.tree-handl').prepend($('<i class="shim icon-folder-close"></i>'));
            }
        }

        function moveRows(id, row) {
            $('.item-of-' + id).insertAfter(row);
            return true;
        }

        // 展开结点
        function expandNode(id, row, table) {
            if (id) {
                var items = '.item-of-' + id, item, wd;
                row.find('.tree-handl i.handl').addClass('icon-folder-open').removeClass('icon-folder-close');
                var left = row.data('left');
                $(items).each(function(i, _item) {
                    item = $(_item);
                    if (item.find('i.shim').length == 0) {
                        addHandl(item.attr('id'), item, table);
                    }
                    if (item.find('td.tree-handl span.chunk').length == 0) {
                        wd = left + 16;
                        item.data('left', wd);
                        item.find('td.tree-handl').prepend($('<span class="chunk" style="width:' + (wd) + 'px;">&nbsp;</span>'));
                    }
                    item.removeClass('hide');
                    if (item.hasClass('expanded')) {
                        expandNode(item.attr('id'), item, table);
                    } else {
                        collapseNode(item.attr('id'), item, table);
                    }
                });
            }
        }

        // 收起结点
        function collapseNode(id, row, table) {
            if (id) {
                var items = '.item-of-' + id, item;
                row.find('.tree-handl i.handl').addClass('icon-folder-close').removeClass('icon-folder-open');
                $(items).each(function(i, _item) {
                    item = $(_item);
                    item.addClass('hide');
                    collapseNode(item.attr('id'), item, table);
                });
            }
        }

        return $(this);
    };

    $.winGoto = function(url) {
        var win = window;
        while (win.location.href != win.parent.location.href) {
            win = win.parent;
        }
        win.location.href = url;
    };
    $.ajax1 = $.ajax;
    var __AJAX = {
        records : {},
        timer : null,
        error_flag : false,
        ajaxReq : null,
        options : {
            dataType : 'text json', // 20s
            timeout : 90000, // 默认的jquery ajax的配置
            timer : 30000, // 断网后,一分钟后重连
            flag : null, // 扩展 唯一标记, 相同标记的禁止叠加请求。
            retry : 0, // 扩展 触发error时的重试次数
            failedData : function(message) {// 扩展,通过error调用success时，传入succes函数的参数。
                return {
                    success : false,
                    msg : message
                };
            }
        },
        msg : {
            zh : {
                timeout : '请求超时。',
                error : '网络错误，无法正常连接网络。',
                parsererror : '数据解析时发生错误，服务端没有返回正确的数据。',
                unknown : '未知错误。'
            }
        },
        dealMsg : function(error_type) {
            var message = ($.inArray(error_type, ['timeout', 'error', 'parsererror']) > -1) ? this.msg['zh'][error_type] : this.msg['zh']['unknown'];
            return message;
        },
        setAjaxHeader : function(xhr, data_type) {
            data_type = data_type.split(' ');
            xhr.setRequestHeader('X-AJAX-TYPE', data_type[data_type.length - 1]);
        },
        send : function(options) {
            var win = window;
            while (win.location.href != win.parent.location.href) {
                win = win.parent;
            }
            var self = __AJAX;
            // will be changed later
            var true_options = $.extend({}, self.options, options), flag = true_options.flag, retry = true_options.retry, failedData = true_options.failedData;
            options.win = win;

            // 如果此次请求处于等待状态，返回什么都不做。
            if ( typeof flag === 'string' && flag.length && self.records[flag] === 1) {
                return false;
            }
            self.records[flag] = 1;

            // 对关键功能加入全局动作
            // 扩展beforeSend
            true_options.beforeSend = function(xhr) {
                self.setAjaxHeader(xhr, this.dataType);
                if ($.isFunction(options.beforeSend)) {
                    options.beforeSend(xhr);
                }
            };
            // 扩展error
            true_options.error = function(xhr, error) {
                var ajaxRes = $.trim(self.ajaxReq.getResponseHeader('X-AJAX-REDIRECT'));
                var ajaxAuth = $.trim(self.ajaxReq.getResponseHeader('X-AJAX-TRANSIT'));
                if (ajaxAuth) {
                    if ($.isFunction(options.transit)) {
                        options.transit(ajaxAuth, ajaxRes);
                    }
                    return;
                } else if (ajaxRes) {
                    if ($.isFunction(options.error)) {
                        options.error(xhr, error);
                    }
                    options.win.location.href = ajaxRes;
                    return;
                } else if (error == 'error' && options.reconnect) {// 网络问题哦
                    self.error_flag = true;
                    // 发生了错误,告诉complete不要执行,因为要继续处理
                    this.beforeSend = function(xhr) {
                        self.setAjaxHeader(xhr, this.dataType);
                    };
                    self.timer = setTimeout(function() {
                        $.ajax1(true_options);
                    }, self.options.timer);
                } else if (retry === 0) {
                    var message = self.dealMsg(error);
                    if ($.isFunction(options.error)) {
                        options.error(xhr, error);
                    }
                    if ($.isFunction(options.success)) {
                        options.success(failedData(message));
                    }
                } else if (retry > 0) {
                    self.error_flag = true;
                    // 发生了错误,告诉complete不要执行,因为要重试
                    true_options.beforeSend = function(xhr) {
                        self.setAjaxHeader(xhr, this.dataType);
                    };
                    $.ajax1(true_options);
                    retry--;
                }
            };
            // 扩展complete。
            true_options.complete = function(xhr, ts) {
                if (!self.error_flag) {
                    if ($.isFunction(options.complete)) {
                        options.complete(xhr, ts);
                    }
                    delete self.records[flag];
                } else {
                    self.error_flag = false;
                    // 争取下一次执行权限
                }
            };
            // 发送请求
            self.ajaxReq = $.ajax1(true_options);
            return self.ajaxReq;
        }
    };
    $.eajax = $.ajax = __AJAX.send;
    // 日期格式化
    Date.prototype.format = function(format) {
        var o = {
            "M+" : this.getMonth() + 1, // month
            "d+" : this.getDate(), // day
            "h+" : this.getHours(), // hour
            "m+" : this.getMinutes(), // minute
            "s+" : this.getSeconds(), // second
            "q+" : Math.floor((this.getMonth() + 3) / 3), // quarter
            "S" : this.getMilliseconds()
        };
        if (/(y+)/.test(format))
            format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
        if (new RegExp("(" + k + ")").test(format))
            format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
        return format;
    };

    $.extend({
        metadata : {
            defaults : {
                type : 'class',
                name : 'metadata',
                cre : /({.*})/,
                single : 'metadata'
            },
            setType : function(type, name) {
                this.defaults.type = type;
                this.defaults.name = name;
            },
            get : function(elem, opts) {
                var settings = $.extend({}, this.defaults, opts);
                // check for empty string in single property
                if (!settings.single.length)
                    settings.single = 'metadata';

                var data = $.data(elem, settings.single);
                // returned cached data if it already exists
                if (data)
                    return data;

                data = "{}";

                if (settings.type == "class") {
                    var m = settings.cre.exec(elem.className);
                    if (m)
                        data = m[1];
                } else if (settings.type == "elem") {
                    if (!elem.getElementsByTagName)
                        return undefined;
                    var e = elem.getElementsByTagName(settings.name);
                    if (e.length)
                        data = $.trim(e[0].innerHTML);
                } else if (elem.getAttribute != undefined) {
                    var attr = elem.getAttribute(settings.name);
                    if (attr)
                        data = attr;
                }

                if (data.indexOf('{') < 0)
                    data = "{" + data + "}";

                data = eval("(" + data + ")");

                $.data(elem, settings.single, data);
                return data;
            }
        }
    });

    $.fn.metadata = function(opts) {
        return $.metadata.get(this[0], opts);
    };

    if ($.validator) {
        $.validator.addMethod('baseurl', function(value, element) {
            return this.optional(element) || /^(https?:\/\/|\/).*$/.test(value);
        }, '请输入正确的URL或以/开头的url路径.');
    }

    $(function() {
        $('.table').uiTable();
        $('input[placeholder], textarea[placeholder]').placeholder();
        if ($.datepicker) {
            $.datepicker.setDefaults({
                dateFormat : 'yy-mm-dd',
                currentText : '今天',
                weekHeader : '周',
                dayNames : ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
                dayNamesMin : ["日", "一", "二", "三", "四", "五", "六"],
                dayNamesShort : ["日", "一", "二", "三", "四", "五", "六"],
                monthNames : ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一", "腊月"],
                monthNamesShort : ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一", "腊月"]
            });
        }
    });

})(jQuery);

(function($) {
    function Placeholder(input) {
        this.input = input;
        if (input.attr('type') == 'password') {
            this.handlePassword();
        }
        // Prevent placeholder values from submitting
        $(input[0].form).submit(function() {
            if (input.hasClass('placeholder') && input[0].value == input.attr('placeholder')) {
                input[0].value = '';
            }
        });
    }


    Placeholder.prototype = {
        show : function(loading) {
            // FF and IE saves values when you refresh the page. If the user refreshes the page with
            // the placeholders showing they will be the default values and the input fields won't be empty.
            if (this.input[0].value === '' || (loading && this.valueIsPlaceholder())) {
                if (this.isPassword) {
                    try {
                        this.input[0].setAttribute('type', 'text');
                    } catch (e) {
                        this.input.before(this.fakePassword.show()).hide();
                    }
                }
                this.input.addClass('placeholder');
                this.input[0].value = this.input.attr('placeholder');
            }
        },
        hide : function() {
            if (this.valueIsPlaceholder() && this.input.hasClass('placeholder')) {
                this.input.removeClass('placeholder');
                this.input[0].value = '';
                if (this.isPassword) {
                    try {
                        this.input[0].setAttribute('type', 'password');
                    } catch (e) {
                    }
                    // Restore focus for Opera and IE
                    this.input.show();
                    this.input[0].focus();
                }
            }
        },
        valueIsPlaceholder : function() {
            return this.input[0].value == this.input.attr('placeholder');
        },
        handlePassword : function() {
            var input = this.input;
            input.attr('realType', 'password');
            this.isPassword = true;
            // IE < 9 doesn't allow changing the type of password inputs
            if ($.browser.msie && input[0].outerHTML) {
                var fakeHTML = $(input[0].outerHTML.replace(/type=(['"])?password\1/gi, 'type=$1text$1'));
                this.fakePassword = fakeHTML.val(input.attr('placeholder')).addClass('placeholder').focus(function() {
                    input.trigger('focus');
                    $(this).hide();
                });
                $(input[0].form).submit(function() {
                    fakeHTML.remove();
                    input.show()
                });
            }
        }
    };
    var NATIVE_SUPPORT = !!("placeholder" in document.createElement("input"));
    $.fn.placeholder = function() {
        return NATIVE_SUPPORT ? this : this.each(function() {
            var input = $(this);
            var placeholder = new Placeholder(input);
            placeholder.show(true);
            input.focus(function() {
                placeholder.hide();
            });
            input.blur(function() {
                placeholder.show(false);
            });

            // On page refresh, IE doesn't re-populate user input
            // until the window.onload event is fired.
            if ($.browser.msie) {
                $(window).load(function() {
                    if (input.val()) {
                        input.removeClass("placeholder");
                    }
                    placeholder.show(true);
                });
                // What's even worse, the text cursor disappears
                // when tabbing between text inputs, here's a fix
                input.focus(function() {
                    if (this.value == "") {
                        var range = this.createTextRange();
                        range.collapse(true);
                        range.moveStart('character', 0);
                        range.select();
                    }
                });
            }
        });
    };
})(jQuery);

function showWaitMask(msg) {
    var win = window;
    while (win.location.href != win.parent.location.href) {
        win = win.parent;
    }
    if (win.Desktop) {
        win.Desktop.showWaitMask(msg);
    }
}

function hideWaitMask() {
    var win = window;
    while (win.location.href != win.parent.location.href) {
        win = win.parent;
    }
    if (win.Desktop) {
        win.Desktop.hideWaitMask();
    }
}

function openTab(url, appID, title, icon) {
    var win = window;
    while (win.location.href != win.parent.location.href) {
        win = win.parent;
    }
    if (win.Nutzp) {
        win.Nutzp.Workbench.addTab('desktop', url, title, icon, appID);
    }
}

function closeTab(appID) {
    var win = window;
    while (win.location.href != win.parent.location.href) {
        win = win.parent;
    }
    if (win.Nutzp) {
        win.Nutzp.Workbench.closeTab(false, appID);
    }
}

function activeTab(appID) {
    var win = window;
    while (win.location.href != win.parent.location.href) {
        win = win.parent;
    }
    if (win.Nutzp) {
        win.Nutzp.Workbench.activeTab('desktop', '', appID);
    }
}

function trayNotify(notify, timeout) {
    var win = window;
    while (win.location.href != win.parent.location.href) {
        win = win.parent;
    }
    if (win.Desktop) {
        win.Desktop.notify(notify, timeout);
    }
}

function transitDialog(transit, url, callback) {
    var win = window;
    while (win.location.href != win.parent.location.href) {
        win = win.parent;
    }
    if (win.showTransitDialog) {
        win.showTransitDialog(transit, url, callback);
    }
}
